using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using cocos2d;
using System.Diagnostics;

namespace Meteorite
{
    public class StoneManage
    {
        
        public enum ObjType
        {
            eObjType_SpeedUp = 0,
            eObjType_Fuel,
            eObjType_Bounus,

            eObjType_Stone1 = 10,
            eObjType_Stone2,
            eObjType_Stone3,
            eObjType_Stone4,
            eObjType_Stone5,
            eObjType_Stone6,
            eObjType_Stone7,
            eObjType_Stone8,
            eObjType_Stone9,
            eObjType_Stone10,


            eObjType_Max,
        };
        Random rand = new Random();

        List<Object> listEntity = new List<Object>();

        public int Level { get; set; }
        int nTick = 0;
        int nSpecialItemCountDown = 0;

        Model SpeedupModel;
        Model FuelModel;
        Model BounusModel;

        Model[] StoneModel = new Model[10];

        const int nTowardStone = 300;
        public StoneManage()
        { 
            Level = 1;
            nTick = 0;
            nSpecialItemCountDown = GameConstant.SpecialCountDown + rand.Next() % GameConstant.SpecialCountDown;
        }

        public void LoadContent(Meteorite game)
        {
            SpeedupModel = game.Content.Load<Model>(GameConstant.Model_Bonus_Boost);
            FuelModel = game.Content.Load<Model>(GameConstant.Model_Bonus_Fuel);
            BounusModel = game.Content.Load<Model>(GameConstant.Model_Bonus_Crytal);

            StoneModel[0] = game.Content.Load<Model>(GameConstant.Model_Stone_1);
            StoneModel[1] = game.Content.Load<Model>(GameConstant.Model_Stone_2);
            StoneModel[2] = game.Content.Load<Model>(GameConstant.Model_Stone_3);
            StoneModel[3] = game.Content.Load<Model>(GameConstant.Model_Stone_4);
            StoneModel[4] = game.Content.Load<Model>(GameConstant.Model_Stone_5);
            StoneModel[5] = game.Content.Load<Model>(GameConstant.Model_Stone_6);
            StoneModel[6] = game.Content.Load<Model>(GameConstant.Model_Stone_7);
            StoneModel[7] = game.Content.Load<Model>(GameConstant.Model_Stone_8);
            StoneModel[8] = game.Content.Load<Model>(GameConstant.Model_Stone_9);
            StoneModel[9] = game.Content.Load<Model>(GameConstant.Model_Stone_10);

            Vector3 p = Meteorite.camera.Position;

            for (int i = 0; i < 10; i++ )
            {
                ObjType Objtype = (ObjType)rand.Next((int)(ObjType.eObjType_Stone1), (int)(ObjType.eObjType_Stone10));
                GenerateObj(Objtype, false, false);
            }
        }

        public void Draw(Matrix View, Matrix Projection)
        {
            foreach (Object e in listEntity)
            {
                e.Draw(View, Projection);
            }
        }

        public List<Object> GetEntityList()
        {
            return listEntity;
        }

        public void GenerateObj(ObjType type,bool bFarthest,bool bTowardShip)
        {
            Object Obj = null;
            switch (type)
            {
                case ObjType.eObjType_SpeedUp:
                    {
                        Obj = new Speedup(SpeedupModel);
                    }
                    break;
                case ObjType.eObjType_Fuel:
                    {
                        Obj = new Fuel(FuelModel);
                    }
                    break;
                case ObjType.eObjType_Bounus:
                    {
                        Obj = new Bounus(BounusModel);
                    }
                    break;
                case ObjType.eObjType_Stone1:
                case ObjType.eObjType_Stone2:
                case ObjType.eObjType_Stone3:
                case ObjType.eObjType_Stone4:
                case ObjType.eObjType_Stone5:
                case ObjType.eObjType_Stone6:
                case ObjType.eObjType_Stone7:
                case ObjType.eObjType_Stone8:
                case ObjType.eObjType_Stone9:
                case ObjType.eObjType_Stone10:
                    {
                        int StoneType = (int)(type - ObjType.eObjType_Stone1);
                        //Debug.WriteLine(string.Format("StoneType={0}", StoneType));
                        Obj = new Stone(StoneModel[StoneType]);

                        Obj.Scale = GameConstant.Stone_Scale + GameConstant.Stone_Scale * (float)Meteorite.random.NextDouble();
                    }
                    break;
                default:
                    break;

            }

            if (type >= ObjType.eObjType_Stone1 && type < ObjType.eObjType_Stone10)
            {
                if (CCDirector.sharedDirector().runningScene is GameScene)
                {
                    UserData.Instance().AddValue(GameConstant.UserData_TotalStone, 1);
                }
            }


            Vector3 Pos = Vector3.Zero;
            if (bTowardShip)
            {
                Pos.X = Meteorite.ship.Position.X;
                Pos.Y = Meteorite.ship.Position.Y;
            }
            else
            {
                if (type >= ObjType.eObjType_Stone1 && type < ObjType.eObjType_Stone10)
                {
                    Pos.X = 1.3f * Meteorite.random.Next(-GameConstant.WindowWidth, GameConstant.WindowWidth);
                    Pos.Y =  1.3f * Meteorite.random.Next(-GameConstant.WindowHeight, GameConstant.WindowHeight);
                }
                else
                {
                    Pos.X = 0.6f*Meteorite.random.Next(-GameConstant.WindowWidth, GameConstant.WindowWidth);
                    Pos.Y = 0.5f * Meteorite.random.Next(-GameConstant.WindowHeight, GameConstant.WindowHeight);
                }
               
            }

            if (bFarthest)
            {
                Pos.Z = Meteorite.camera.Position.Z - 10000;
            }
            else
            {
                Pos.Z = Meteorite.random.Next(-10000, 0);
            }
            Obj.Position = Pos;
            int zBase = GameScene.nScore <= 10000 ? GameScene.nScore / 40 : 300;
            Obj.Velocity = new Vector3(0, 0, zBase+Meteorite.random.Next(600, 2000) * 1.0f);
            float fRotationBase = 0.1f;
            Obj.Rotation = new Vector3(fRotationBase * (float)Meteorite.random.NextDouble(), fRotationBase * (float)Meteorite.random.NextDouble(), fRotationBase * (float)Meteorite.random.NextDouble());
            Obj.RotationSpeed = new Vector3(fRotationBase * (float)Meteorite.random.NextDouble(), fRotationBase * (float)Meteorite.random.NextDouble(), fRotationBase * (float)Meteorite.random.NextDouble());
            Obj.Valid = true;

            listEntity.Add(Obj);
        }

        public void Update(GameTime gameTime)
        {
            nTick++;

            ObjType Objtype = (ObjType)rand.Next((int)(ObjType.eObjType_Stone1), (int)(ObjType.eObjType_Stone10)+1);
            //ObjType Objtype = ObjType.eObjType_Stone10;
            if (GameScene.nScore <= 300)
            {
                if (0 == nTick % 12)
                {
                    GenerateObj(Objtype, true, 0 == rand.Next() % 25 ? true : false);
                }
            }
            else if (GameScene.nScore <= 1000)
            {
                if (0 == nTick % 10)
                {
                    GenerateObj(Objtype, true, 0 == rand.Next() % 23 ? true : false);
                }
            }
            else if (GameScene.nScore <= 2000)
            {
                if (0 == nTick % 9)
                {
                    GenerateObj(Objtype, true, 0 == rand.Next() % 21 ? true : false);
                }
            }
            else if (GameScene.nScore <= 3000)
            {
                if (0 == nTick % 8)
                {
                    GenerateObj(Objtype, true, 0 == rand.Next() % 19 ? true : false);
                }
            }
            else if (GameScene.nScore <= 4000)
            {
                if (0 == nTick % 7)
                {
                    GenerateObj(Objtype, true, 0 == rand.Next() % 17 ? true : false);
                }
            }
            else if (GameScene.nScore <= 5000)
            {
                if (0 == nTick % 6)
                {
                    GenerateObj(Objtype, true, 0 == rand.Next() % 15 ? true : false);
                }
            }
            else if (GameScene.nScore <= 6000)
            {
                if (0 == nTick % 5)
                {
                    GenerateObj(Objtype, true, 0 == rand.Next() % 13 ? true : false);
                }
            }
            else if (GameScene.nScore <= 7000)
            {
                if (0 == nTick % 5)
                {
                    GenerateObj(Objtype, true, 0 == rand.Next() % 12 ? true : false);
                }
            }
            else if (GameScene.nScore <= 8000)
            {
                if (0 == nTick % 4)
                {
                    GenerateObj(Objtype, true, 0 == rand.Next() % 10 ? true : false);
                }
            }
            else if (GameScene.nScore <= 9000)
            {
                if (0 == nTick % 4)
                {
                    GenerateObj(Objtype, true, 0 == rand.Next() % 8 ? true : false);
                }
            }
            else if (GameScene.nScore <= 10000)
            {
                if (0 == nTick %3)
                {
                    GenerateObj(Objtype, true, 0 == rand.Next() % 7 ? true : false);
                }
            }
            else if (GameScene.nScore <= 15000)
            {
                if (0 == nTick % 3)
                {
                    GenerateObj(Objtype, true, 0 == rand.Next() % 6 ? true : false);
                }
            }
            else
            {
                if (0 == nTick % 3)
                {
                    GenerateObj(Objtype, true, 0 == rand.Next() % 5 ? true : false);
                }
            }

            if (nSpecialItemCountDown > 0)
            {
                nSpecialItemCountDown--;
            }
            else
            {
                nSpecialItemCountDown = GameConstant.SpecialCountDown + rand.Next() % GameConstant.SpecialCountDown;
                ObjType BonusItemType = (ObjType)rand.Next((int)(ObjType.eObjType_SpeedUp), (int)(ObjType.eObjType_Bounus)+1);
                GenerateObj(BonusItemType, true, 1==rand.Next()%2 ? true : false);
            }


            List<Object> list = new List<Object>();
            //Recycle
            foreach (Object o in listEntity)
            {
                if( o.Valid )
                {
                    if ((o.Position.Z - Meteorite.camera.Position.Z) > 1000)
                    {
                        list.Add(o);
                    }
                    else
                    {
                        o.Update(gameTime);
                    }
                }
            }

            //Record user data
            for (int i = 0; i < list.Count; i++)
            {
                listEntity.Remove(list[i]);
                if (CCDirector.sharedDirector().runningScene is GameScene)
                {
                    GameScene.nScore += GameConstant.Score_Per_Stone;
                }
            }

        }
    }
}
